#include "bh750.h"
#include "delay.h"
#include "stm32f10x.h"
/*
 *==============================================================================
 *函数名称：IIC_Delay
 *函数功能：IIC延时
 *输入参数：无
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void IIC_Delay (void)
{
	u8 t = 10;
	while (t--);
}
/*
 *==============================================================================
 *函数名称：I2C_Start
 *函数功能：IIC起始信号
 *输入参数：无
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void I2C_Start (void)
{
	BH1750_SDA_Set();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SDA_Clr();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
}
/*
 *==============================================================================
 *函数名称：I2C_Stop
 *函数功能：IIC终止信号
 *输入参数：无
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void I2C_Stop (void)
{
	BH1750_SDA_Clr();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SDA_Set();
}
/*
 *==============================================================================
 *函数名称：IIC_Ack
 *函数功能：CPU产生一个ACK信号
 *输入参数：无
 *返回值：无
 *备  注：无
 *==============================================================================
 */
void IIC_Ack (void)
{
	BH1750_SDA_Clr();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
	BH1750_SDA_Set();
}
/*
 *==============================================================================
 *函数名称：IIC_NAck
 *函数功能：CPU产生一个NACK信号
 *输入参数：无
 *返回值：无
 *备  注：无
 *==============================================================================
 */
void IIC_NAck (void)
{
	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();	
}
/*
 *==============================================================================
 *函数名称：I2C_WaitAck
 *函数功能：IIC等待应答
 *输入参数：无
 *返回值：0：未收到应答信号；1：收到应答信号
 *备  注：无
 *==============================================================================
 */
u8 I2C_WaitAck (void)
{
	u8 re;

	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	if (BH1750_SDA_DATA())
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	
	BH1750_SCL_Clr();
	IIC_Delay();
	
	return re;
}
/*
 *==============================================================================
 *函数名称：Send_Byte
 *函数功能：写入一个字节
 *输入参数：dat：需要写入的数据
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void Send_Byte (u8 dat)
{
	u8 i;

	for (i = 0;i < 8;i ++)
	{
		// 发送数据时，从高位依次写入
		if (dat & 0x80)
		{
			BH1750_SDA_Set();
		}
		else
		{
			BH1750_SDA_Clr();
		}
		IIC_Delay();
		BH1750_SCL_Set();
		IIC_Delay();
		BH1750_SCL_Clr();
		
		// dat左移1位
		dat <<= 1;
	}
}
/*
 *==============================================================================
 *函数名称：IIC_Read_Byte
 *函数功能：IIC读取一个字节数据
 *输入参数：无
 *返回值：无
 *备  注：读取到的一个字节数据
 *==============================================================================
 */
u8 IIC_Read_Byte (void)
{
	u8 i;
	u8 value;
	
	// 高位在前
	value = 0;
	
	// 循环读取8bit数据
	for (i = 0; i < 8; i ++)
	{
		value <<= 1;   // 循环左移一位
		
		BH1750_SCL_Set();
		IIC_Delay();
		
		// 如果是“1”
		if (BH1750_SDA_DATA())
		{
			value ++;
		}
		
		BH1750_SCL_Clr();
		IIC_Delay();
	}
	
	return value;
}
//BH1750写一个字节
//返回值	成功：0		失败：非0 
/*
 *==============================================================================
 *函数名称：BH1750_Byte_Write
 *函数功能：BH1750写一个字节
 *输入参数：data：要写入的数据
 *返回值：0：写入成功；1/2：写入失败
 *备  注：无
 *==============================================================================
 */
u8 BH1750_Byte_Write (u8 data)
{
	I2C_Start();
	
	// 发送从设备地址，0：写
	Send_Byte (BH1750_Addr | 0);
	
	// 收到应答信号
	if(I2C_WaitAck() == 1)
	{
		return 1;
	}
	//发送控制命令
	Send_Byte(data);
	
	// 收到应答信号
	if(I2C_WaitAck() == 1)
	{
		return 2;
	}
	
	I2C_Stop();
	
	return 0;
}


/*
 *==============================================================================
 *函数名称：Drv_Bh1750_Read_Measure
 *函数功能：读取BH1750测量数据
 *输入参数：无
 *返回值：0：读取失败；其他：光照强度
 *备  注：无
 *==============================================================================
 */
u16 Drv_Bh1750_Read_Measure (void)
{
	u16 receData = 0;
	
	I2C_Start();
	
	// 发送从设备地址，1：读
	Send_Byte(BH1750_Addr | 1);
	
	if(I2C_WaitAck() == 1)
	{
		return 0;
	}
	
	// 读取高八位
	receData = IIC_Read_Byte();
	IIC_Ack();
	
	// 读取低八位
	receData = (receData << 8) + IIC_Read_Byte();
	IIC_NAck();
	I2C_Stop();
	
	return receData;   // 返回读取到的数据
}

/*
 *==============================================================================
 *函数名称：Drv_Bh1750_Init
 *函数功能：初始化BH1750
 *输入参数：无
 *返回值：无
 *备  注：无
 *==============================================================================
 */
void Drv_Bh1750_Init (void)
{
	// 结构体定义
 	GPIO_InitTypeDef  GPIO_InitStructure;
	
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	// 初始化GPIO结构体
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;   // 开漏输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);

	// 给一个停止信号, 复位I2C总线上的所有设备到待机模式
	I2C_Stop();
	
	// BH1750上电
	BH1750_Byte_Write(POWER_ON);
	
	// 复位BH1750
	BH1750_Byte_Write(MODULE_RESET);
	
	// 写入测量模式
	BH1750_Byte_Write(Measure_Mode);
}

/*
 *==============================================================================
 *函数名称：Med_Bh1750_GetLightIntensity
 *函数功能：获取光照强度
 *输入参数：无
 *返回值：光照强度
 *备  注：分辨率	光照强度（单位lx）=（High Byte  + Low Byte）/ 1.2 * 测量精度
 *==============================================================================
 */
float Med_Bh1750_GetLightIntensity (void)
{
	return (float)(Drv_Bh1750_Read_Measure() / 1.1f * Resolurtion);   //返回测量光照强度
}
